DEBUG = 0;

var User = Base.extend( {
	constructor : function(user_type, name) {
		this.name = name;
		this.user_type = user_type;
		if (DEBUG) console.log('Hi ' + user_type + ' ' + this.name);
		$('body').addClass(user_type);

		this.connect();

		$('#'+user_type+'_panel').show();
		$('.user_action').click(jQuery.proxy(this.do_action, this));
		$(document).bind('keydown', 'space', function(){
			$('.user_action:visible:first').trigger('click');
			return false;
		});
	},
	name : '',
	user_type : 'player',
	competition_stats : {
		start : 0, // ms since epoch when the current competition was opened
		answered: 0, // ms since epoch when the play clicked answer
		miliseconds: 0 // store ms it took to answer
	},
	ws : '',
	// Run on button.user_action clicks
	do_action : function(event) {
		var action = $(event.target).val();
		this.ws.send('action:' + action);
	},

	/**********************************
	 * 'set_' actions to run onmessage
	 **********************************/
	// Update User count
	set_user_count : function(val) {
		$('#game_info-user_count').html(val);
	},
	// Update UI
	set_state : function(state) {
		if (DEBUG) console.log('State to set: ', state);
		$('.state_panel').hide(); // Clear all user actions, what to show will follow
		$('#'+this.user_type+'_panel .'+state+'_state').show(); // Show current
	},
	// Show confirmed users
	set_confirmed : function(confirmations) {
		if (DEBUG) console.log('Set confirmed: ', confirmations);
		$('.player_confirmations').html(confirmations);
	},
	// Show competition results
	set_results : function(results) {
		if (DEBUG) console.log('Set results: ', results);
		$('.player_results').html(results);
	},
	
	connect : function() {
		this.ws = new WebSocket('ws://' + window.location.host + '/' + this.user_type);
		this.ws.onmessage = jQuery.proxy(this.onmessage, this);
		this.ws.onopen = jQuery.proxy(this.onopen, this);
		this.ws.onerror = jQuery.proxy(this.onerror, this);
		this.ws.onclose = jQuery.proxy(this.onerror, this); // do error handler for close also
	},

	// Handle data from server
	onmessage : function(e) {
		var data = eval('(' + e.data + ')'); // Convert JSON
		for (key in data) {
			if (DEBUG) console.log(key, data[key]);
			this[key](data[key]);
		}
	},
	// Init user with server
	onopen : function() {
		this.ws.send('name:' + this.name);
		$('body').removeClass('disconnected');
	},
	onerror : function(event) {
		console.log(event);
		$('body').addClass('disconnected');
		
		if ( confirm('A communications error has occurred, reload?') ) {
			window.location.reload();
		}
	}
});

var Player = User.extend( {
	constructor : function(name) {
		this.base('player', name);
		$('#player_name').html(name);
	},
	
	do_action : function(event) {
		var action = $(event.target).val();
		if ( action == 'answer' ) {
			this.competition_stats.answered = (new Date).getTime();
			this.competition_stats.miliseconds = this.competition_stats.answered - this.competition_stats.start;
			$(event.target).fadeOut();
			this.ws.send('action:answer='+this.competition_stats.miliseconds);
			if (DEBUG) console.log('Time to answer: ' + (this.competition_stats.miliseconds / 1000) + ' seconds');
		}
		else {
			this.base(event);
		}
	},
	// run when player clicks confirm button
	// this context is the Player object
	confirm : function(event) {
		$(event.target).fadeOut();
	},
	set_state : function(state) {
		this.base(state['name']);

		switch (state['name']) {
		
		// Description: Player must confirm ready to play
		// Action: Player must click 'Ready'
		// Wait on: Admin to 'Start'
		case 'ready':
			this.set_results('');
			
			break;
		
		// Description: Admin requests and view players that have confirmed ready
		// Wait on: Admin to click 'Start'
		case 'confirm':
			$('.confirm_state button').one( 'click', jQuery.proxy( this.confirm, this ) );
			$('.competition_state button').show(); // Show in the hidden panel for next time
			this.competition_stats.start = 0;
			this.competition_stats.answered = 0;
			this.competition_stats.miliseconds = 0;
			break;

		// Description: Player can buzz in
		// Action: Player may click 'Answer'
		// Early Termination: On Admin 'Finish'
		case 'competition':
			$('.confirm_state button').show();
			if (!this.competition_stats.start) // Set if still cleared
				this.competition_stats.start = (new Date).getTime();
			break;
		
		default: // Empty
	}
}
});

var Admin = User.extend( {
	constructor : function(name) {
		this.base('admin', name);
		$('#game_info').show();
	},
	set_state : function(state) {
		
		this.base(state['name']);
		
		// Additional actions can be performed below
		switch (state.name) {
		
		// Description: Admin requests and view players that have confirmed ready
		// Wait on: Admin to click 'Start'
		case 'confirm':
			break;
			
			// Description: Game play is underway
			// Wait on: Admin to click 'Finish'
		case 'competition':
			break;
			
		default: // Empty
		}
	}
});

var Presenter = User.extend( {
	constructor : function(name) {
		this.base('presenter', name);
	},
	set_state : function(state) {
		
		this.base(state['name']);
		
		// Additional actions can be performed below
		switch (state.name) {
		
		// Description: Admin requests and view players that have confirmed ready
		// Wait on: Admin to click 'Start'
		case 'confirm':
			break;
			
			// Description: Game play is underway
			// Wait on: Admin to click 'Finish'
		case 'competition':
			break;
			
		default: // Empty
		}
	}
});

// MAIN
$(document).ready(function() {
	if ( "WebSocket" in window ) {
		$('#login').show();
	}
	else {
		$('#tests_failed').show();
		return;
	}
	$('#user_name').val($.cookie('user_name') || 'User'+Math.floor(Math.random()*10000)).select().focus();
	$('#login button.user_type').click(function() {
		var user_name = $('#user_name').val();
		if ( !user_name ) {
			$('#user_name').css('background-color', 'red').focus();
			return false;
		}
		$.cookie('user_name', user_name);
		$('#login').hide();
		$('#game_info-user_name').html(user_name);
		switch (this.value) {
		case 'player':
			var user = new Player(user_name);
			break;
		case 'admin':
			var user = new Admin(user_name);
			break;
		case 'presenter':
			var user = new Presenter(user_name);
			break;
		default:
			if (DEBUG) console.log('Unknown user type');
		}
	});
	var url_parts = window.location.href.split('#');
	if ( url_parts[1] && url_parts[1] == 'admin' ) {
		var password = prompt('Password:');
		$.ajax({
			"url" : "/admin",
			"type" : "POST",
			"dataType" : "json",
			"data" : {
				"password" : password
			},
			"success" : function(data) {
				if ( data.success ) {
					var user = new Admin('Admin');
					$('#login').hide();
				}
				else {
					alert('Wrong password.');
				}
			}
		});
	}
});
